<?php

namespace App\HttpController\XApp\Cashbook\Web;


use App\Common\User\WxUser;
use App\HttpController\ControllerWeb;
use App\Model\t_a_cashbook_record;
use Carbon\Carbon;
use XWX\Common\H;
use XWX\Common\XArray\XArray;

class Api extends ControllerWeb
{
    public function getUserID()
    {
        return "oeJaEvw1_iLnXFmlKqV3-aTUgzQ4";
    }

    public function index()
    {
        $this->commonR()->setData('types', $this->funcGetTypes());

        $this->funcWriteCommonR();
    }

    public function add()
    {
        $id = $this->reqParam('id');

        $entity_cashbook = null;
        if (H::funcStrHasAnyText($id))
        {
            $entity_cashbook = t_a_cashbook_record::funcXLoad($this->db(), $this->funcGetX(), $id);
        }

        $types = $this->funcGetTypes();

        $this->commonR()->setData('entity_cashbook', $entity_cashbook);
        $this->commonR()->setData('types', $types);


        $this->funcWriteCommonR();
    }


    //添加记录
    public function func_cashbook_add()
    {
        $str_date = $this->reqParam("date");
        $type = $this->reqParam("type");
        $ab_type = $this->reqParam("ab_type");
        $num = H::funcStrToFloat($this->reqParam("num"));
        $desc = $this->reqParam("desc");
        $id = $this->reqParam("id");


        if (H::funcStrIsNullOrEmpty($str_date))
        {
            return $this->funcWriteErr(-200, '请输入日期');
        }

        if ($num <= 0)
        {
            return $this->funcWriteErr(-300, '请输入金额');
        }

        if (!in_array($ab_type, ['+', '-']))
        {
            return $this->funcWriteErr(-350, '类型有误');
        }


        $date = Carbon::parse($str_date);


        $entity_cashbook = null;
        if (H::funcStrHasAnyText($id))
        {
            //更新
            $entity_cashbook = t_a_cashbook_record::funcXLoad($this->db(), $this->funcGetX(), $id);
        }
        else
        {
            //添加
            $key = "{$this->getUserID()}|" . H::now()->toDateTimeString();

            $entity_cashbook = new t_a_cashbook_record();
            $entity_cashbook->cashrec_x_id = $this->funcGetX();
            $entity_cashbook->cashrec_wxuser_id = $this->getUserID();
            $entity_cashbook->cashrec_key = $key;
            $entity_cashbook->funcInsert();

            $entity_cashbook = t_a_cashbook_record::funcGetEntityByKey($key);
        }


        $entity_cashbook->cashrec_date = $date->toDateString();
        $entity_cashbook->cashrec_type = $type;
        $entity_cashbook->cashrec_ab_type = $ab_type;
        $entity_cashbook->cashrec_num = $num;
        $entity_cashbook->cashrec_desc = $desc;

        $num_r = $ab_type == '-' ? "{$ab_type}{$num}" : $num;
        $entity_cashbook->cashrec_num_r = $num_r;
        $entity_cashbook->funcUpdate();


        $this->commonR()->setData('entity_cashbook', $entity_cashbook);


        $this->funcWriteCommonR();
    }


    //列表
    function func_cashbook_list()
    {
        $yyyyMM = $this->reqParam("yyyyMM");


        $r = $this->funcCheckMonth();
        if ($r->err())
        {
            return $this->funcWriteErrR($r);
        }


        $date_first = Carbon::parse($yyyyMM . '-01');
        $date_last = $date_first->copy()->addMonthNoOverflow();


        $count = 0;
        $list = $this->db()
            ->where('cashrec_x_id', $this->funcGetX())
            ->where('cashrec_wxuser_id', $this->getUserID())
            ->where('cashrec_date', $date_first->toDateTimeString(), '>=')
            ->where('cashrec_date', $date_last->toDateTimeString(), '<')
            ->orderBy('cashrec_date', 'DESC')
            ->orderBy('cashrec_create_date')
            ->get(t_a_cashbook_record::table(), [$this->funcGetPageIndexXPage(), $this->funcGetPageSize()]);
        $arr_x = XArray::funcIns($list);

        /** @var Carbon[] $list_date */
        $list_date = [];
        foreach ($list as $k => $v)
        {
            $cashrec_date = $v['cashrec_date'];
            $list_date[$cashrec_date] = Carbon::parse($cashrec_date);
        }

        $list_ = [];
        foreach ($list_date as $date)
        {
            $data = [];
            $data['cashrec_date'] = $date->format('d日') . "-星期{$date->dayOfWeek}";

            $list_date_cashrec = $arr_x->where('cashrec_date', $date->toDateTimeString())->get();
            $list_sub = [];
            foreach ($list_date_cashrec as $cashrec)
            {
                $cashrec_type = $cashrec['cashrec_desc'];
                if (H::funcStrIsNullOrEmpty($cashrec_type))
                {
                    $cashrec_type = $this->funcGetTypes($cashrec['cashrec_type']);
                }

                $list_sub[] = [
                    'cashrec_type' => $cashrec_type,
                    'entity_cashrec' => $cashrec,
                ];
            }
            $data['list'] = $list_sub;

            $list_[] = $data;
        }


        $this->commonR()->setData('list', $list_);


        $this->funcWriteCommonR();
    }

    //
    function func_cashbook_type_list()
    {
        $yyyyMM = $this->reqParam("yyyyMM");
        $type = $this->reqParam('type');

        $r = $this->funcCheckMonth();
        if ($r->err())
        {
            return $this->funcWriteErrR($r);
        }


        $date_first = Carbon::parse($yyyyMM . '-01');
        $date_last = $date_first->copy()->addMonthNoOverflow();


        $count = 0;
        $list = $this->db()
            ->where('cashrec_x_id', $this->funcGetX())
            ->where('cashrec_wxuser_id', $this->getUserID())
            ->where('cashrec_date', $date_first->toDateTimeString(), '>=')
            ->where('cashrec_date', $date_last->toDateTimeString(), '<')
            ->where('cashrec_type', $type)
            ->orderBy('cashrec_date', 'DESC')
            ->orderBy('cashrec_create_date')
            ->get(t_a_cashbook_record::table(), [$this->funcGetPageIndexXPage(), $this->funcGetPageSize()]);

        $list_ = [];
        foreach ($list as $item)
        {
            $entity = new t_a_cashbook_record($item);
            $cashrec_desc = $entity->cashrec_desc;
            if (H::funcStrIsNullOrEmpty($cashrec_desc))
            {
                $cashrec_desc = $this->funcGetTypes($entity->cashrec_type);
            }

            $list_[] = [
                'date' => $entity->cashrec_date->toDateString(),
                'cashrec_desc' => $cashrec_desc,
                'entity_cashrec' => $entity,
            ];
        }


        $this->commonR()->setData('type', $this->funcGetTypes($type));
        $this->commonR()->setData('count', $count);
        $this->commonR()->setData('list', $list_);

        $this->funcWriteCommonR();
    }

    //总数
    function func_cashbook_sum()
    {
        $yyyyMM = $this->reqParam("yyyyMM");


        if (H::funcStrIsNullOrEmpty($yyyyMM))
        {
            return $this->funcWriteErr(-200, '系统异常，月份为空');
        }


        $date_first = Carbon::parse($yyyyMM . '-01');
        $date_last = $date_first->copy()->addMonthNoOverflow();


        $this->commonR()->setData("cash_pay", $this->funcGetCash($this->getUserID(), $date_first, $date_last));
        $this->commonR()->setData("cash_income", $this->funcGetCash($this->getUserID(), $date_first, $date_last, '+'));

        $this->funcWriteCommonR();
    }


    //月统计
    function func_cashbook_cart__month()
    {
        $yyyyMM = $this->reqParam("yyyyMM");


        $r = $this->funcCheckMonth();
        if ($r->err())
        {
            return $this->funcWriteErrR($r);
        }


        $date_first = Carbon::parse($yyyyMM . '-01');
        $date_last = $date_first->copy()->addMonthNoOverflow();


        $query = $this->db()
            ->where('cashrec_x_id', $this->funcGetX())
            ->where('cashrec_ab_type', '-')
            ->where('cashrec_date', $date_first->toDateTimeString(), '>=')
            ->where('cashrec_date', $date_last->toDateTimeString(), '<')
            ->where('cashrec_wxuser_id', $this->getUserID())
            ->groupBy('cashrec_type');

        $list = $query->get(t_a_cashbook_record::table(), null, 'cashrec_type, SUM(cashrec_num) AS _SUM');


        $colors['空'] = "#30a5ff|#62b9fb";
        $colors['零食'] = "#ffb53e|#fac878";
        $colors['网购'] = "#1ebfae|#3cdfce";
        $colors['娱乐'] = "#f9243f|#f6495f";
        $colors['早餐'] = "#33FF66|#66FF33";
        $colors['午餐'] = "#CCFF33|#FFCC33";
        $colors['晩餐'] = "#CC33FF|#FF33CC";
        $colors['煲汤'] = "#339966|#669933";
        $colors['运动'] = "#333399|#75D1D1";
        $colors['水果'] = "#3399FF|#6699FF";
        $colors['交通'] = "#9933CC|#CC33B3";
        $colors['房租'] = "#9933FF|#CC33FF";

        $sum_pay = $this->funcGetCash($this->getUserID(), $date_first, $date_last);


        //饼图参数
        $list_x = [];
        foreach ($list as $item)
        {
            $type = H::funcArrayGet($item, 'cashrec_type');
            $sum = floatval(H::funcArrayGet($item, '_SUM'));
            
            $type_name = $this->funcGetTypes($type);
            $data = [
                'value' => $sum,
                'type' => $type,
                'label' => $type_name,
                'pen' => round($sum / $sum_pay * 100, 1)
            ];

            //颜色
            $type_color = H::funcArrayGet($colors, $type_name);
            if ($type_color === null)
            {
                $data['color'] = "#30a5ff";
                $data['highlight'] = "#62b9fb";
            }
            else
            {
                $type_color_split = explode('|', $type_color);

                $data['color'] = $type_color_split[0];
                $data['highlight'] = $type_color_split[1];
            }

            $list_x[] = $data;
        }


        //块参数

        $list_xe = [];
        $list_xe_coloc = [];
        foreach ($list as $item)
        {
            $type = H::funcArrayGet($item, 'cashrec_type');
            $sum = H::funcArrayGet($item, '_SUM');

            $type_name = $this->funcGetTypes($type);
            $data = [
                'value' => $sum,
                'name' => $type_name,
            ];

            $list_xe[] = $data;

            //颜色
            $type_color = H::funcArrayGet($colors, $type_name);
            if ($type_color === null)
            {
                $list_xe_coloc[] = "#30a5ff";
            }
            else
            {
                $type_color_split = explode('|', $type_color);

                $list_xe_coloc[] = $type_color_split[0];
            }
        }

        $this->commonR()->setData("list", $list_x);
        $this->commonR()->setData("list_xe", $list_xe);
        $this->commonR()->setData("list_xe_coloc", $list_xe_coloc);


        $this->funcWriteCommonR();
    }

    //年统计
    function func_cashbook_cart__year()
    {
        $yyyy = $this->reqParam("yyyy");
        $type = $this->reqParam('type');

        if (H::funcStrIsNullOrEmpty($yyyy))
        {

            return $this->funcGetR(-200, '系统异常，月份为空');
        }


        $date_first = Carbon::parse($yyyy . '-01-01');
        $date_last = $date_first->copy()->addYear();
        if ($date_first->year == H::today()->year)
        {
            //本年，只统计到当月
            $date_last = Carbon::parse(H::today()->format('Y-m-01'))->addMonthNoOverflow();
        }

        $list_pay = $this->funcListGroupByMonth($this->getUserID(), $date_first, $date_last, '-', $type);
        $list_income = $this->funcListGroupByMonth($this->getUserID(), $date_first, $date_last, '+', $type);


        $list_pay_data = [];
        $list_income_data = [];

        /** @var Carbon[] $list_month */
        $list_month = H::funcCarbonGetMonths($date_first, $date_last->copy()->subMonthNoOverflow());
        foreach ($list_month as $month)
        {
            //支出
            $month_sum_pay = H::funcArrayGet($list_pay, $month->format('Y-m'), 0.0);
            $list_pay_data[] = $month_sum_pay;

            //收入
            $month_sum_income = H::funcArrayGet($list_income, $month->format('Y-m'), 0.0);
            $list_income_data[] = $month_sum_income;
        }


        $list_month_str = H::funcCarbonGetMonths($date_first, $date_last->copy()->subMonthNoOverflow(), 'm月');

        $this->commonR()->setData('list_month_str', $list_month_str);
        $this->commonR()->setData('list_pay_data', $list_pay_data);
        $this->commonR()->setData('list_income_data', $list_income_data);


        $this->funcWriteCommonR();
    }


    /**
     * 检查月份
     *
     * @return \XWX\Common\XReturn
     */
    function funcCheckMonth()
    {
        $yyyyMM = $this->reqParam("yyyyMM");


        if (H::funcStrIsNullOrEmpty($yyyyMM))
        {

            return $this->funcGetR(-200, '系统异常，月份为空');
        }


        return $this->funcGetR(0);
    }


    /**
     * 支出或者收入总值
     *
     * @param $wx_from
     * @param Carbon $date_first
     * @param Carbon $date_last
     * @param string $ab_type -:支出;+:收入;
     * @return float
     * @throws \EasySwoole\Mysqli\Exceptions\ConnectFail
     * @throws \EasySwoole\Mysqli\Exceptions\PrepareQueryFail
     * @throws \Throwable
     */
    function funcGetCash($wx_from, Carbon $date_first, Carbon $date_last, $ab_type = "-")
    {
        $sum = $this->db()
            ->where('cashrec_x_id', $this->funcGetX())
            ->where('cashrec_wxuser_id', $wx_from)
            ->where('cashrec_ab_type', $ab_type)
            ->where('cashrec_date', $date_first->toDateTimeString(), '>=')
            ->where('cashrec_date', $date_last->toDateTimeString(), '<')
            ->sum(t_a_cashbook_record::table(), 'cashrec_num');
        if ($sum == null)
        {
            $sum = 0;
        }

        return floatval($sum);
    }

    function funcListGroupByMonth($wx_from, Carbon $date_first, Carbon $date_last, $cashrec_ab_type = '-', $type = null)
    {
        $query = $this->db()
            ->where('cashrec_x_id', $this->funcGetX())
            ->where('cashrec_ab_type', $cashrec_ab_type)
            ->where('cashrec_date', $date_first->toDateTimeString(), '>=')
            ->where('cashrec_date', $date_last->toDateTimeString(), '<')
            ->where('cashrec_wxuser_id', $wx_from)
            ->groupBy('MON__');

        //类型
        if (H::funcStrHasAnyText($type))
        {
            $query->where('cashrec_type', $type);
        }

        $list = $query->get(t_a_cashbook_record::table(), null, "date_format(cashrec_date, '%Y-%m') AS MON__,SUM(cashrec_num) AS SUM__");
        $list_ = [];
        foreach ($list as $item)
        {
            $month = H::funcArrayGet($item, 'MON__');
            $sum = H::funcStrToFloat(H::funcArrayGet($item, 'SUM__'));

            $list_[$month] = $sum;
        }

        return $list_;
    }

    function funcGetTypes($key = null)
    {
        $types = [
            "breakfast" => "早餐",
            "lunch" => "午餐",
            "dinner" => "晩餐",
            "food" => "零食",
            "shop" => "网购",
            "entertainment" => "娱乐",
            "soup" => "煲汤",
            "sports" => "运动",
            "fruit" => "水果",
            "traffic" => "交通",
            "rent" => "房租",
            "" => "其他",
        ];

        if ($key !== null)
        {
            return H::funcArrayGet($types, $key);
        }


        return $types;
    }
}